'''
Created on 22-12-2010

@author: Morsio
'''
import threading


class EventQueue(object):
    def __init__(self):
        self._worker = threading.Thread(target = self)
        self._events = []
        self.lock = threading.Lock()
        self.finish = False
        self._something_to_do = threading.Semaphore(0)
        self._worker.start()
        
    def __call__(self):
        while True:
            self._something_to_do.acquire()
            task = self._events.pop(0)
            task[0]._handler(task[1])
            self.lock.acquire()
            finish = self.finish
            self.lock.release()
            if finish == True and self._events.__len__() == 0:
                break
        pass
    
    def Append(self, event, args):
        self._events.append((event, args))
        self._something_to_do.release()
        pass


class Event(object):

    queues = dict()

    def __init__(self, handler = None):
        self.SetHandler(handler)
        
    def SetHandler(self, handler):
        self._handler = handler

    def __lshift__(self, handler):
        self.SetHandler(handler)
        return self
    
    def __call__(self, args, queue = "main"):
        Event._AddQueue(queue)
        Event.queues[queue].Append(self, args)
        pass
    
    @classmethod
    def _AddQueue(cls, queue):
        if queue not in Event.queues.keys():
            Event.queues[queue] = EventQueue()
    @classmethod
    def Finalize(cls):
        for q in Event.queues.itervalues():
            q.lock.acquire()
            q.finish = True
            q.lock.release()
            
def foo(arg):
    print 'hello'

if __name__ == "__main__":
    evt = Event()
    evt <<= foo

    evt(None)

    Event.Finalize()